bitkeeper revision 1.1159.1.395 (4190ab80qQIIPeM49q40ES01DxL7Ng)
authorcl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Tue, 9 Nov 2004 11:35:28 +0000 (11:35 +0000)
committercl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Tue, 9 Nov 2004 11:35:28 +0000 (11:35 +0000)
Move shared_info pointer from exec_domain to domain and add vcpu_info pointer
in exec_domain.

14 files changed:
xen/arch/x86/domain.c
xen/arch/x86/irq.c
xen/arch/x86/time.c
xen/arch/x86/traps.c
xen/arch/x86/x86_32/entry.S
xen/arch/x86/x86_32/seg_fixup.c
xen/common/dom0_ops.c
xen/common/domain.c
xen/common/keyhandler.c
xen/common/schedule.c
xen/include/asm-x86/x86_32/asm_defns.h
xen/include/public/xen.h
xen/include/xen/event.h
xen/include/xen/sched.h

index af7fdc757ed0a8ba3ff0f12b6c829cb4565eda0f..e95fc73be2a7841ad862105a59abd3c1e4299b03 100644 (file)
@@ -215,19 +215,21 @@ void free_perdomain_pt(struct exec_domain *d)
     free_xenheap_page((unsigned long)d->mm.perdomain_pt);
 }
 
-void arch_do_createdomain(struct exec_domain *d)
+void arch_do_createdomain(struct exec_domain *ed)
 {
+    struct domain *d = ed->domain;
     d->shared_info = (void *)alloc_xenheap_page();
     memset(d->shared_info, 0, PAGE_SIZE);
+    ed->vcpu_info = &d->shared_info->vcpu_data[ed->eid];
     d->shared_info->arch.mfn_to_pfn_start = 
        virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
-    SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d->domain);
+    SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
     machine_to_phys_mapping[virt_to_phys(d->shared_info) >> 
                            PAGE_SHIFT] = INVALID_P2M_ENTRY;
 
-    d->mm.perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page();
-    memset(d->mm.perdomain_pt, 0, PAGE_SIZE);
-    machine_to_phys_mapping[virt_to_phys(d->mm.perdomain_pt) >> 
+    ed->mm.perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page();
+    memset(ed->mm.perdomain_pt, 0, PAGE_SIZE);
+    machine_to_phys_mapping[virt_to_phys(ed->mm.perdomain_pt) >> 
                            PAGE_SHIFT] = INVALID_P2M_ENTRY;
 }
 
@@ -826,12 +828,12 @@ int construct_dom0(struct domain *p,
     }
 
     /* Set up shared-info area. */
-    update_dom_time(ed->shared_info);
-    ed->shared_info->domain_time = 0;
+    update_dom_time(p->shared_info);
+    p->shared_info->domain_time = 0;
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        ed->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
-    ed->shared_info->n_vcpu = 1;
+        p->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+    p->shared_info->n_vcpu = 1;
 
     /* Install the new page tables. */
     __cli();
@@ -848,7 +850,7 @@ int construct_dom0(struct domain *p,
     si = (start_info_t *)vstartinfo_start;
     memset(si, 0, PAGE_SIZE);
     si->nr_pages     = p->tot_pages;
-    si->shared_info  = virt_to_phys(ed->shared_info);
+    si->shared_info  = virt_to_phys(p->shared_info);
     si->flags        = SIF_PRIVILEGED | SIF_INITDOMAIN;
     si->pt_base      = vpt_start;
     si->nr_pt_frames = nr_pt_pages;
index 5bbec081fddd4082e47bd3816436d6e69f7ce33b..32fa237747e4775f6fcfa458cc0907ec7a99be7f 100644 (file)
@@ -212,7 +212,7 @@ int pirq_guest_unmask(struct domain *d)
     irq_desc_t    *desc;
     unsigned int   i, j, pirq;
     u32            m;
-    shared_info_t *s = d->exec_domain[0]->shared_info;
+    shared_info_t *s = d->shared_info;
 
     for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ )
     {
index be9f477ba58df6d6ae022f4ebcb32ef8e69a39e3..06eed7c4404730304dc0338d886f3c20f6734ee5 100644 (file)
@@ -318,7 +318,7 @@ void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base)
 
     write_unlock_irq(&time_lock);
 
-    update_dom_time(current->shared_info);
+    update_dom_time(current->domain->shared_info);
 }
 
 
index 6164b15177f225953662eacd005fa31836d21137..aff2f134e40e4b2b533ffa288036b320e1bbeb1a 100644 (file)
@@ -231,7 +231,7 @@ static inline void do_trap(int trapnr, char *str,
     gtb->cs         = ti->cs;
     gtb->eip        = ti->address;
     if ( TI_GET_IF(ti) )
-        ed->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
+        ed->vcpu_info->evtchn_upcall_mask = 1;
     return; 
 
  xen_fault:
@@ -302,7 +302,7 @@ asmlinkage void do_int3(struct xen_regs *regs, long error_code)
     gtb->cs         = ti->cs;
     gtb->eip        = ti->address;
     if ( TI_GET_IF(ti) )
-        ed->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
+        ed->vcpu_info->evtchn_upcall_mask = 1;
 }
 
 asmlinkage void do_double_fault(void)
@@ -393,7 +393,7 @@ asmlinkage void do_page_fault(struct xen_regs *regs, long error_code)
     gtb->cs         = ti->cs;
     gtb->eip        = ti->address;
     if ( TI_GET_IF(ti) )
-        ed->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
+        ed->vcpu_info->evtchn_upcall_mask = 1;
     return; 
 
  xen_fault:
@@ -510,7 +510,7 @@ asmlinkage void do_general_protection(struct xen_regs *regs, long error_code)
     gtb->cs         = ti->cs;
     gtb->eip        = ti->address;
     if ( TI_GET_IF(ti) )
-        ed->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
+        ed->vcpu_info->evtchn_upcall_mask = 1;
     return;
 
  gp_in_kernel:
index d0dba03cdec465a7e87c7e2989c2908124e09eed..67b2009245cff27583a01b93ee1aeb74f2c6f4b1 100644 (file)
@@ -196,12 +196,12 @@ restore_all_guest:
 /* No special register assumptions */
 failsafe_callback:
         GET_CURRENT(%ebx)
-        movl DOMAIN_processor(%ebx),%eax
+        movl EDOMAIN_processor(%ebx),%eax
         shl  $4,%eax
         lea  guest_trap_bounce(%eax),%edx
-        movl DOMAIN_failsafe_addr(%ebx),%eax
+        movl EDOMAIN_failsafe_addr(%ebx),%eax
         movl %eax,GTB_eip(%edx)
-        movl DOMAIN_failsafe_sel(%ebx),%eax
+        movl EDOMAIN_failsafe_sel(%ebx),%eax
         movw %ax,GTB_cs(%edx)
         call create_bounce_frame
         subl $16,%esi                # add DS/ES/FS/GS to failsafe stack frame
@@ -253,24 +253,24 @@ test_all_events:
         notl %ecx
         cli                             # tests must not race interrupts
 /*test_softirqs:*/  
-        movl DOMAIN_processor(%ebx),%eax
+        movl EDOMAIN_processor(%ebx),%eax
         shl  $6,%eax                    # sizeof(irq_cpustat) == 64
         test %ecx,SYMBOL_NAME(irq_stat)(%eax,1)
         jnz  process_softirqs
 /*test_guest_events:*/
-        movl DOMAIN_shared_info(%ebx),%eax
-        testb $0xFF,SHINFO_upcall_mask(%eax)
+        movl EDOMAIN_vcpu_info(%ebx),%eax
+        testb $0xFF,VCPUINFO_upcall_mask(%eax)
         jnz  restore_all_guest
-        testb $0xFF,SHINFO_upcall_pending(%eax)
+        testb $0xFF,VCPUINFO_upcall_pending(%eax)
         jz   restore_all_guest
-        movb $1,SHINFO_upcall_mask(%eax) # Upcalls are masked during delivery
+        movb $1,VCPUINFO_upcall_mask(%eax) # Upcalls are masked during delivery
 /*process_guest_events:*/
-        movl DOMAIN_processor(%ebx),%edx
+        movl EDOMAIN_processor(%ebx),%edx
         shl  $4,%edx                     # sizeof(guest_trap_bounce) == 16
         lea  guest_trap_bounce(%edx),%edx
-        movl DOMAIN_event_addr(%ebx),%eax
+        movl EDOMAIN_event_addr(%ebx),%eax
         movl %eax,GTB_eip(%edx)
-        movl DOMAIN_event_sel(%ebx),%eax
+        movl EDOMAIN_event_sel(%ebx),%eax
         movw %ax,GTB_cs(%edx)
         call create_bounce_frame
         jmp  restore_all_guest
@@ -290,7 +290,7 @@ create_bounce_frame:
         test $2,%cl
         jz   1f /* jump if returning to an existing ring-1 activation */
         /* obtain ss/esp from TSS -- no current ring-1 activations */
-        movl DOMAIN_processor(%ebx),%eax
+        movl EDOMAIN_processor(%ebx),%eax
         /* next 4 lines multiply %eax by 8320, which is sizeof(tss_struct) */
         movl %eax, %ecx
         shll $7, %ecx
@@ -362,7 +362,7 @@ crash_domain_fixup3:
 
         ALIGN
 process_guest_exception_and_events:        
-        movl DOMAIN_processor(%ebx),%eax
+        movl EDOMAIN_processor(%ebx),%eax
         shl  $4,%eax
         lea  guest_trap_bounce(%eax),%edx
         testb $~0,GTB_flags(%edx)
index 601ee27827fdf3c735648665b66107225c2b9e33..996fd09e8a016ed707443f72e3cad7733df2703a 100644 (file)
@@ -472,7 +472,7 @@ int gpf_emulate_4gb(struct xen_regs *regs)
         gtb->cs         = ti->cs;
         gtb->eip        = ti->address;
         if ( TI_GET_IF(ti) )
-            d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
+            d->vcpu_info->evtchn_upcall_mask = 1;
     }
 
     return 1;
index e1046064a7620eddcd3e7e17e1d4185f60132b8c..58484efb11c3f79a404ce422635f8316e70ebde4 100644 (file)
@@ -372,7 +372,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         op->u.getdomaininfo.max_pages   = d->max_pages;
         op->u.getdomaininfo.cpu_time    = ed->cpu_time;
         op->u.getdomaininfo.shared_info_frame = 
-            __pa(ed->shared_info) >> PAGE_SHIFT;
+            __pa(d->shared_info) >> PAGE_SHIFT;
 
         if ( op->u.getdomaininfo.ctxt != NULL )
         {
index 5ca8697cbe8600061b5d95df3df4f6b8f4107da1..102afeff64e04f4a351f4475b5a4847b0fb10002 100644 (file)
@@ -243,7 +243,7 @@ void domain_destruct(struct domain *d)
 
     for_each_exec_domain(d, ed)
         free_perdomain_pt(ed);
-    free_xenheap_page((unsigned long)d->exec_domain[0]->shared_info);
+    free_xenheap_page((unsigned long)d->shared_info);
 
     free_domain_struct(d);
 }
@@ -278,7 +278,7 @@ int final_setup_guestos(struct domain *p, dom0_builddomain_t *builddomain)
         goto out;
 
     /* Set up the shared info structure. */
-    update_dom_time(p->exec_domain[0]->shared_info);
+    update_dom_time(p->shared_info);
 
     set_bit(DF_CONSTRUCTED, &p->d_flags);
 
index b8acae71a1bde71d47a98c89ba096709887af4b1..c5ab06145aa44b670805c8eccf49ba76f8b601e2 100644 (file)
@@ -94,7 +94,7 @@ void do_task_queues(unsigned char key)
             }
         }
 
-        page = virt_to_page(d->exec_domain[0]->shared_info);
+        page = virt_to_page(d->shared_info);
         printk("Shared_info@%08x: caf=%08x, taf=%08x\n",
                page_to_phys(page), page->count_info,
                page->u.inuse.type_info);
@@ -105,8 +105,8 @@ void do_task_queues(unsigned char key)
                    ed->processor,
                    test_bit(EDF_RUNNING, &ed->ed_flags) ? 'T':'F',
                    ed->ed_flags,
-                   ed->shared_info->vcpu_data[0].evtchn_upcall_pending, 
-                   ed->shared_info->vcpu_data[0].evtchn_upcall_mask);
+                   ed->vcpu_info->evtchn_upcall_pending, 
+                   ed->vcpu_info->evtchn_upcall_mask);
         }
         printk("Notifying guest...\n"); 
         send_guest_virq(d->exec_domain[0], VIRQ_DEBUG);
index 3bc93b7bfa17cb729306f2baea2164765926ce44..22b97b6ef8010f79ad1d7121c66258e3fbc64776 100644 (file)
@@ -222,7 +222,7 @@ void domain_wake(struct exec_domain *d)
 long do_block(void)
 {
     ASSERT(current->id != IDLE_DOMAIN_ID);
-    current->shared_info->vcpu_data[0].evtchn_upcall_mask = 0;
+    current->vcpu_info->evtchn_upcall_mask = 0;
     set_bit(EDF_BLOCKED, &current->ed_flags);
     TRACE_2D(TRC_SCHED_BLOCK, current->id, current);
     __enter_scheduler();
@@ -390,7 +390,7 @@ void __enter_scheduler(void)
 
     /* Ensure that the domain has an up-to-date time base. */
     if ( !is_idle_task(next->domain) )
-        update_dom_time(next->shared_info);
+        update_dom_time(next->domain->shared_info);
 
     if ( unlikely(prev == next) )
         return;
@@ -468,7 +468,7 @@ static void t_timer_fn(unsigned long unused)
     TRACE_0D(TRC_SCHED_T_TIMER_FN);
 
     if ( !is_idle_task(p->domain) ) {
-        update_dom_time(p->shared_info);
+        update_dom_time(p->domain->shared_info);
         send_guest_virq(p, VIRQ_TIMER);
     }
 
@@ -482,7 +482,7 @@ static void dom_timer_fn(unsigned long data)
     struct domain *p = (struct domain *)data;
     struct exec_domain *ed = p->exec_domain[0];
     TRACE_0D(TRC_SCHED_DOM_TIMER_FN);
-    update_dom_time(ed->shared_info);
+    update_dom_time(p->shared_info);
     send_guest_virq(ed, VIRQ_TIMER);
 }
 
@@ -496,7 +496,7 @@ static void fallback_timer_fn(unsigned long unused)
     TRACE_0D(TRC_SCHED_FALLBACK_TIMER_FN);
 
     if ( !is_idle_task(p) )
-        update_dom_time(ed->shared_info);
+        update_dom_time(p->shared_info);
 
     fallback_timer[ed->processor].expires = NOW() + MILLISECS(500);
     add_ac_timer(&fallback_timer[ed->processor]);
index 37efa678795b1eb9a1bd0ed89f9831fccc500d45..bca45ed53f93a74833072c1672061c23016e31cc 100644 (file)
 #define XREGS_fs       0x3C
 #define XREGS_gs       0x40
 
-/* Offsets in 'struct domain' --- AUTO-GENERATE ME! */
-#define DOMAIN_processor       0
-#define DOMAIN_shared_info     4
-#define DOMAIN_event_sel       8
-#define DOMAIN_event_addr     12
-#define DOMAIN_failsafe_sel   16
-#define DOMAIN_failsafe_addr  20
-
-/* Offsets in shared_info_t --- AUTO-GENERATE ME! */
-#define SHINFO_upcall_pending /* 0 */
-#define SHINFO_upcall_mask       1
+/* Offsets in 'struct exec_domain' --- AUTO-GENERATE ME! */
+#define EDOMAIN_processor       0
+#define EDOMAIN_vcpu_info       4
+#define EDOMAIN_event_sel       8
+#define EDOMAIN_event_addr     12
+#define EDOMAIN_failsafe_sel   16
+#define EDOMAIN_failsafe_addr  20
+
+/* Offsets in vcpu_info_t --- AUTO-GENERATE ME! */
+#define VCPUINFO_upcall_pending /* 0 */
+#define VCPUINFO_upcall_mask       1
 
 /* Offsets in 'struct guest_trap_bounce' --- AUTO-GENERATE ME! */
 #define GTB_error_code    0
index ca3cc054d6dc725b9daccbf54618be0a07aeadf2..eafb7bd639ca4508dba6f3ed1d20c92592e2868b 100644 (file)
@@ -253,46 +253,49 @@ typedef struct
 /* No support for multi-processor guests. */
 #define MAX_VIRT_CPUS 4
 
+/*
+ * Per-VCPU information goes here. This will be cleaned up more when Xen 
+ * actually supports multi-VCPU guests.
+ */
+typedef struct vcpu_info_st
+{
+    /*
+     * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
+     * a pending notification for a particular VCPU. It is then cleared 
+     * by the guest OS /before/ checking for pending work, thus avoiding
+     * a set-and-check race. Note that the mask is only accessed by Xen
+     * on the CPU that is currently hosting the VCPU. This means that the
+     * pending and mask flags can be updated by the guest without special
+     * synchronisation (i.e., no need for the x86 LOCK prefix).
+     * This may seem suboptimal because if the pending flag is set by
+     * a different CPU then an IPI may be scheduled even when the mask
+     * is set. However, note:
+     *  1. The task of 'interrupt holdoff' is covered by the per-event-
+     *     channel mask bits. A 'noisy' event that is continually being
+     *     triggered can be masked at source at this very precise
+     *     granularity.
+     *  2. The main purpose of the per-VCPU mask is therefore to restrict
+     *     reentrant execution: whether for concurrency control, or to
+     *     prevent unbounded stack usage. Whatever the purpose, we expect
+     *     that the mask will be asserted only for short periods at a time,
+     *     and so the likelihood of a 'spurious' IPI is suitably small.
+     * The mask is read before making an event upcall to the guest: a
+     * non-zero mask therefore guarantees that the VCPU will not receive
+     * an upcall activation. The mask is cleared when the VCPU requests
+     * to block: this avoids wakeup-waiting races.
+     */
+    u8 evtchn_upcall_pending;
+    u8 evtchn_upcall_mask;
+    u8 pad0, pad1;
+} PACKED vcpu_info_t;
+
 /*
  * Xen/guestos shared data -- pointer provided in start_info.
  * NB. We expect that this struct is smaller than a page.
  */
 typedef struct shared_info_st
 {
-    /*
-     * Per-VCPU information goes here. This will be cleaned up more when Xen 
-     * actually supports multi-VCPU guests.
-     */
-    struct {
-        /*
-         * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
-         * a pending notification for a particular VCPU. It is then cleared 
-         * by the guest OS /before/ checking for pending work, thus avoiding
-         * a set-and-check race. Note that the mask is only accessed by Xen
-         * on the CPU that is currently hosting the VCPU. This means that the
-         * pending and mask flags can be updated by the guest without special
-         * synchronisation (i.e., no need for the x86 LOCK prefix).
-         * This may seem suboptimal because if the pending flag is set by
-         * a different CPU then an IPI may be scheduled even when the mask
-         * is set. However, note:
-         *  1. The task of 'interrupt holdoff' is covered by the per-event-
-         *     channel mask bits. A 'noisy' event that is continually being
-         *     triggered can be masked at source at this very precise
-         *     granularity.
-         *  2. The main purpose of the per-VCPU mask is therefore to restrict
-         *     reentrant execution: whether for concurrency control, or to
-         *     prevent unbounded stack usage. Whatever the purpose, we expect
-         *     that the mask will be asserted only for short periods at a time,
-         *     and so the likelihood of a 'spurious' IPI is suitably small.
-         * The mask is read before making an event upcall to the guest: a
-         * non-zero mask therefore guarantees that the VCPU will not receive
-         * an upcall activation. The mask is cleared when the VCPU requests
-         * to block: this avoids wakeup-waiting races.
-         */
-        u8 evtchn_upcall_pending;
-        u8 evtchn_upcall_mask;
-        u8 pad0, pad1;
-    } PACKED vcpu_data[MAX_VIRT_CPUS];  /*   0 */
+    vcpu_info_t vcpu_data[MAX_VIRT_CPUS];  /*   0 */
 
     u32 n_vcpu;
 
index 86af2954a71bf00a8e6509db903ce731ce633a3a..517b22ed4d622e8d93cfabd5af655cc9260b6bca 100644 (file)
@@ -23,7 +23,7 @@
 static inline void evtchn_set_pending(struct domain *d, int port)
 {
     struct exec_domain *ed = d->exec_domain[0];
-    shared_info_t *s = ed->shared_info;
+    shared_info_t *s = d->shared_info;
     int            running;
 
     /* These three operations must happen in strict order. */
@@ -32,7 +32,7 @@ static inline void evtchn_set_pending(struct domain *d, int port)
          !test_and_set_bit(port>>5, &s->evtchn_pending_sel) )
     {
         /* The VCPU pending flag must be set /after/ update to evtchn-pend. */
-        set_bit(0, &s->vcpu_data[0].evtchn_upcall_pending);
+        set_bit(0, &ed->vcpu_info->evtchn_upcall_pending);
 
         /*
          * NB1. 'flags' and 'processor' must be checked /after/ update of
@@ -72,7 +72,7 @@ static inline void send_guest_pirq(struct domain *d, int pirq)
 }
 
 #define event_pending(_d)                                     \
-    ((_d)->shared_info->vcpu_data[0].evtchn_upcall_pending && \
-     !(_d)->shared_info->vcpu_data[0].evtchn_upcall_mask)
+    ((_d)->vcpu_info->evtchn_upcall_pending && \
+     !(_d)->vcpu_info->evtchn_upcall_mask)
 
 #endif /* __XEN_EVENT_H__ */
index 83a160cc5ca9f6851728ad3d85df5fc96f8cd40e..17e58f6337a9931a74da12c3503713f78542991f 100644 (file)
@@ -63,7 +63,7 @@ struct exec_domain
     u32 processor;               /* 00: current processor */
 
     /* An unsafe pointer into a shared data area. */
-    shared_info_t *shared_info;  /* 04: shared data area */
+    vcpu_info_t *vcpu_info;      /* 04: vcpu info pointer */
 
     /*
      * Return vectors pushed to us by guest OS.
@@ -106,6 +106,8 @@ struct domain {
     domid_t  id;
     s_time_t create_time;
 
+    shared_info_t *shared_info;       /* shared data area */
+
     spinlock_t       page_alloc_lock; /* protects all the following fields  */
     struct list_head page_list;       /* linked list, of size tot_pages     */
     struct list_head xenpage_list;    /* linked list, of size xenheap_pages */